package com.gmrz.uaf.protocol.v1.schema;

import com.gmrz.uaf.common.Constants;
import com.gmrz.uaf.protocol.v1.json.UAFSchemaBuilder;
import com.gmrz.util.Convert;
import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;

import java.util.List;

public class RegistrationResponse {

	@SerializedName("header")
	@Expose
	private OperationHeader operationHeader;
	private FinalChallengeParams finalChallengeParams = null;

	@SerializedName("fcParams")
	@Expose
	private String fcParamsBase64;
	private Constants.AuthenticatorStatus status = Constants.AuthenticatorStatus.ACTIVE;
	private Base64URLEncoded<FinalChallengeParams> fcParams;

	@SerializedName("assertions")
	@Expose
	private List<RegistrationAssertion> assertions;

	@SerializedName("registration")
	@Expose
	private AuthenticatorRegistration registration;

	public AuthenticatorRegistration getRegistration() {
		return registration;
	}

	public void setRegistration(AuthenticatorRegistration registration) {
		this.registration = registration;
	}

	public OperationHeader getOperationHeader() {
		return operationHeader;
	}

	public void setOperationHeader(OperationHeader operationHeader) {
		this.operationHeader = operationHeader;
	}

	public void setRegistrationStatus(Constants.AuthenticatorStatus status) {
		this.status = status;
	}

	public Constants.AuthenticatorStatus getRegistrationStatus() {
		return this.status;
	}

	public RegistrationResponse withOperationHeader(
			OperationHeader operationHeader) {
		this.operationHeader = operationHeader;
		return this;
	}

	public FinalChallengeParams getFinalChallengeParams() {
		Gson gson = UAFSchemaBuilder.getGson();
		try {
			String fcpUFT8String = Convert.fromUtf8(Convert
					.fromBase64(fcParamsBase64));
			finalChallengeParams = gson.fromJson(
					fcpUFT8String, FinalChallengeParams.class);
		} catch (Exception e) {
			throw new RuntimeException(
					"FinalChallengeParams is not UTF-8 encoded");
		}
		return this.finalChallengeParams;
	}

	public String getFCPBase64() {
		return fcParamsBase64;
	}

	public void setFinalChallengeParams(
			FinalChallengeParams finalChallengeParams) {
		this.finalChallengeParams = finalChallengeParams;
		this.fcParams = new Base64URLEncoded<FinalChallengeParams>(finalChallengeParams);
		Gson gson = UAFSchemaBuilder.getGson();
		String fcpString = gson.toJson(finalChallengeParams,
				FinalChallengeParams.class);
		try {
			byte[] fcpStringBytes = Convert.toUtf8(fcpString);
			this.fcParamsBase64 = Convert.toBase64(fcpStringBytes);
		} catch (Exception e) {
			throw new RuntimeException("UTF-8 encoding is not supported.");
		}
	}

	public void setFinalChallengeParams(String fcpBase64) {
		TypeToken<FinalChallengeParams> fcParams = new TypeToken<FinalChallengeParams>() {};
		Gson gson = new Gson();
		this.finalChallengeParams = gson.fromJson(
				fcpBase64, fcParams.getType());
		this.fcParams = new Base64URLEncoded<FinalChallengeParams>(this.finalChallengeParams);
	}

	public RegistrationResponse withFinalChallengeParams(
			FinalChallengeParams finalChallengeParams) {
		setFinalChallengeParams(finalChallengeParams);
		return this;
	}

	public List<RegistrationAssertion> getAssertions() {
		return assertions;
	}

	public void setAssertions(
			List<RegistrationAssertion> authenticatorRegistrationAssertions) {
		this.assertions = authenticatorRegistrationAssertions;
	}

	public RegistrationResponse withAssertions(
			List<RegistrationAssertion> authenticatorRegistrationAssertions) {
		this.assertions = authenticatorRegistrationAssertions;
		return this;
	}

}
